home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / graphics / qrt.lzh / PATTERN.C < prev    next >
C/C++ Source or Header  |  1989-02-16  |  5KB  |  230 lines

  1. /**********************************************************
  2.  
  3.                 Pattern and texture module
  4.  
  5.  **********************************************************/
  6.  
  7. #include "qrt.h"
  8. #include "pattern.h"
  9.  
  10. /* #define PATTERNDEBUG 1 */
  11.  
  12.  
  13. /**********************************************************
  14.  
  15.     Given two coordinates on the surface of an object,
  16.     and a pointer to a colorinfo structure, this routine
  17.     fills the structure with the objects color info at
  18.     this location. If the object does not have an associated
  19.     pattern, its default colorinfo is returned.  The
  20.     routine returns TRUE if the pattern is hit, FALSE
  21.     otherwise.
  22.  
  23.  **********************************************************/
  24.  
  25. int Find_Color(obj, pattern, loc, cinfo, xmult, ymult)
  26.   OBJ_PTR     obj;
  27.   PATTERN_PTR pattern;
  28.   VECT_PTR    loc;
  29.   CINFO_PTR   cinfo;
  30.   float       xmult, ymult;
  31. {
  32.   PATTERN_PTR   patt;
  33.   float         modpos1, modpos2, pos1, pos2;
  34.   int           modx, mody;
  35.  
  36.  
  37.   if (pattern==NULL) {                      /* no pattern */
  38.     copy_colorinfo(cinfo,&(obj->cinfo));
  39.     return(FALSE);
  40.   }
  41.  
  42. # ifdef ROBUST
  43.     if (pattern->type != PATT_HEADER)
  44.       Error(INTERNAL_ERROR,1001);
  45.  
  46.     if ((xmult==0) || (ymult==0))
  47.       Error(ZERO_MULTIPLIER,1002);
  48. # endif
  49.  
  50.   /* find object relative position */
  51.  
  52.   (*(ObjData[obj->type].RelPos))(obj,loc,&pos1,&pos2);
  53.  
  54.   pos1 /= xmult;                            /* x and y multipliers */
  55.   pos2 /= ymult;                            /* for pattern sizing  */
  56.  
  57.   modx = (int)(pos1 / (pattern->xsize));
  58.   if (pos1<0) modx--;
  59.  
  60.   mody = (int)(pos2 / (pattern->ysize));
  61.   if (pos2<0) mody--;
  62.  
  63.   modpos1 = pos1 - ((float)modx * pattern->xsize);
  64.   modpos2 = pos2 - ((float)mody * pattern->ysize);
  65.  
  66. # ifdef PATTERNDEBUG
  67.     printf("FINDCOLOR: modpos1,2 = %f %f\n",modpos1, modpos2);
  68.     printf("           mod x,y   = %d %d\n",modx, mody);
  69.     printf("           mult1,2   = %f %f\n",xmult,ymult);
  70. # endif
  71.  
  72.   patt = pattern->child;
  73.  
  74.   while (patt!=NULL) {
  75.  
  76.     THEWORLD.pattern_matches++;
  77.  
  78.     if ((*(PattData[patt->type].PattHit))(modpos1, modpos2, patt)) {
  79.  
  80.       copy_colorinfo(cinfo,&(patt->cinfo));
  81.       return(TRUE);
  82.     }
  83.  
  84.     patt = patt->sibling;
  85.   }
  86.  
  87.   copy_colorinfo(cinfo,&(obj->cinfo));
  88.   return(FALSE);
  89. }
  90.  
  91.  
  92. /**********************************************************
  93.  
  94.          Determines if point is inside rectangle
  95.  
  96.  **********************************************************/
  97.  
  98. int Rect_Hit(pos1, pos2, patt)
  99.   float pos1, pos2;
  100.   PATTERN_PTR patt;
  101. {
  102.  
  103. # ifdef PATTERNDEBUG
  104.   printf("RECT_HIT: sx,y = %f %f\n",patt->startx,patt->starty);
  105.   printf("          ex,y = %f %f\n",patt->endx,patt->endy);
  106. # endif
  107.  
  108. # ifdef ROBUST
  109.     if (patt->type != RECT_PATTERN)
  110.       Error(INTERNAL_ERROR,1003);
  111. # endif
  112.  
  113.   if ( (pos1 > patt->startx) &&
  114.        (pos1 < patt->endx)   &&
  115.        (pos2 > patt->starty) &&
  116.        (pos2 < patt->endy) )      return(TRUE);
  117.  
  118.   return(FALSE);
  119. }
  120.  
  121.  
  122. /**********************************************************
  123.  
  124.          Determines if point is inside circle
  125.  
  126.  **********************************************************/
  127.  
  128. int Circle_Hit(pos1, pos2, patt)
  129.   float pos1, pos2;
  130.   PATTERN_PTR patt;
  131. {
  132.   float rad, a, b;
  133.  
  134. # ifdef ROBUST
  135.     if (patt->type != CIRCLE_PATTERN)
  136.       Error(INTERNAL_ERROR,1004);
  137. # endif
  138.  
  139.   a = (pos1 - patt->radius);      /* bug in damn compiler  */
  140.   b = (pos2 - patt->radius);      /* we have to break up   */
  141.                                   /* long float operations */
  142.   rad = sqr(a)+sqr(b);
  143.  
  144. # ifdef PATTERNDEBUG
  145.     printf("CIRC_HIT\n");
  146.     printf("  p1, p2 = %f %f\n",pos1,pos2);
  147.     printf("  rad    = %f\n",patt->radius);
  148.     printf(" crad    = %f\n",rad);
  149. # endif
  150.  
  151.   if (rad <= sqr(patt->radius)) return(TRUE);
  152.  
  153.   return(FALSE);
  154. }
  155.  
  156.  
  157. /**********************************************************
  158.  
  159.    Determines if point px, py intersects line x1,y1,x2,y2.
  160.    Returns true if it does.
  161.  
  162.  **********************************************************/
  163.  
  164. int line_intersect(px, py, x1, y1, x2, y2)
  165.   float px, py, x1, y1, x2, y2;
  166. {
  167.   float t;
  168.  
  169.   x1 -= px; x2 -= px;           /* translate line */
  170.   y1 -= py; y2 -= py;
  171.  
  172.   if ((y1 > 0) && (y2 > 0)) return(FALSE);
  173.   if ((y1 < 0) && (y2 < 0)) return(FALSE);
  174.   if ((x1 < 0) && (x2 < 0)) return(FALSE);
  175.  
  176.   if (y1 == y2) {
  177.     if (y1 != 0) return(FALSE);
  178.     if ((x1 > 0) || (x2 > 0)) return(FALSE);
  179.     return(TRUE);
  180.   }
  181.  
  182.   t = (-y1) / (y2 - y1);
  183.  
  184.   if ((x1 + t * (x2 - x1)) > 0) return(TRUE);
  185.   return(FALSE);
  186. }
  187.  
  188. /**********************************************************
  189.  
  190.          Determines if point is inside Polygon
  191.  
  192.  **********************************************************/
  193.  
  194. int Poly_Hit(pos1, pos2, patt)
  195.   float pos1, pos2;
  196.   PATTERN_PTR patt;
  197. {
  198.   float xpos, ypos, nxpos, nypos;
  199.   PATTERN_PTR lseg;
  200.   int count;
  201.  
  202. # ifdef ROBUST
  203.     if (patt->type != POLY_PATTERN)
  204.       Error(INTERNAL_ERROR,1005);
  205. # endif
  206.  
  207.   lseg = patt->link;
  208.  
  209.   if (lseg == NULL) Error(INTERNAL_ERROR,1006);
  210.  
  211.   count = 0;
  212.  
  213.   while (lseg->link != NULL) {
  214.  
  215.      if (line_intersect( pos1, pos2,
  216.                          lseg->startx, lseg->starty,
  217.                          lseg->link->startx,
  218.                          lseg->link->starty) )
  219.        count++;
  220.  
  221.      lseg = lseg->link;
  222.   }
  223.  
  224.   if ((count % 2) == 0) return(FALSE);
  225.   return(TRUE);
  226. }
  227.  
  228.  
  229.  
  230.